/*
 * The contents of this web application are subject to the Mozilla Public License Version 
 * 1.1 (the "License"); you may not use this web application except in compliance with 
 * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
 * for the specific language governing rights and limitations under the License.
 * 
 * The Original Code is owned by and the Initial Developer of the Original Code is 
 * Composite A/S (Danish business reg.no. 21744409). All Rights Reserved
 * 
 * Section 11 of the License is EXPRESSLY amended to include a provision stating 
 * that any dispute, including but not limited to disputes related to the enforcement 
 * of the License, to which Composite A/S as owner of the Original Code, as Initial 
 * Developer or in any other role, becomes a part to shall be governed by Danish law 
 * and be initiated before the Copenhagen City Court ("K�benhavns Byret")            
 */

using System;
using System.Collections.Generic;
using Composite.Functions;
using Composite.C1Console.Security;
using Composite.Core.Logging;

namespace Composite.Plugins.Functions.FunctionProviders.StandardFunctionProvider.Foundation
{
    internal abstract class StandardFunctionBase : IFunction
    {
        private EntityTokenFactory _entityTokenFactory;

        internal StandardFunctionBase(string name, string namespaceName, Type returnType, EntityTokenFactory entityTokenFactory)
        {
            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
            if (string.IsNullOrEmpty(namespaceName)) throw new ArgumentNullException("namespaceName");
            if (entityTokenFactory == null) throw new ArgumentNullException("entityTokenFactory");

            this.Namespace = namespaceName;
            this.Name = name;
            this.ReturnType = returnType;
            
            _entityTokenFactory = entityTokenFactory;

            this.ResourceHandleNameStem = string.Format("{0}.{1}", this.Namespace, this.Name);
        }



        public string Name { get; private set; }

        public string Namespace { get; protected set; }

        public string Description
        {
            get
            {
                return LocalizationToken("description");
            }
        }

        public Type ReturnType { get; private set; }


        public IEnumerable<ParameterProfile> ParameterProfiles
        {
            get
            {

                foreach (StandardFunctionParameterProfile param in this.StandardFunctionParameterProfiles)
                {
                    string labelString;
                    string helpString;

                    if (string.IsNullOrEmpty(param.CustomLabel) == false)
                    {
                        labelString = param.CustomLabel;
                    }
                    else
                    {
                        labelString = LocalizationToken(string.Format("param.{0}.label", param.Name));
                    }

                    if (string.IsNullOrEmpty(param.CustomHelpText) == false)
                    {
                        helpString = param.CustomHelpText;
                    }
                    else
                    {
                        helpString = LocalizationToken(string.Format("param.{0}.help", param.Name));
                    }

                    yield return new ParameterProfile(param.Name, param.Type, param.IsRequired, param.FallbackValueProvider,
                        param.WidgetFunctionProvider, labelString, new HelpDefinition(helpString));
                }
            }
        }

        protected virtual IEnumerable<StandardFunctionParameterProfile> StandardFunctionParameterProfiles 
        {
            get
            {
                yield break;
            }
        }

        public abstract object Execute(ParameterList parameters, FunctionContextContainer context);

        public EntityToken EntityToken
        {
            get { return _entityTokenFactory.CreateEntityToken(this); }
        }

        private string LocalizationToken(string functionLocalPart)
        {
            return string.Format( "${{Composite.Plugins.StandardFunctions,{0}.{1}}}", this.ResourceHandleNameStem, functionLocalPart ); 
        }

        public string ResourceHandleNameStem {get; protected set; }
    }
}
